/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.vasthu.core.service;

import com.vasthu.api.dao.BillDAO;
import com.vasthu.api.dao.BillInfoDAO;
import com.vasthu.api.dao.PurchasedItemDAO;
import com.vasthu.api.dao.ReturnedDAO;
import com.vasthu.api.dao.StockDAO;
import com.vasthu.api.domain.*;
import com.vasthu.api.service.BillInfoManagerService;
import com.vasthu.core.dao.*;
import com.vasthu.gui.VstTableItemSelectable;
import com.vasthu.utility.DateTimeUtils;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;

/**
 *
 * @author moremada
 */
public class BillInfoManagerServiceImpl implements BillInfoManagerService {

    //BillInfoDAO billInfoDAO;
    BillDAO billDAO;
    StockDAO stockDAO;
    PurchasedItemDAO purchasedItemDAO;
    ReturnedDAO returnedDAO;
    static Logger logger = Logger.getLogger(BillInfoManagerServiceImpl.class);

    public BillInfoManagerServiceImpl() {
        //billInfoDAO = new BillInfoDAOImpl();
        billDAO = new BillDAOImpl();
        stockDAO = new StockDAOImpl();
        purchasedItemDAO = new PurchasedItemDAOImpl();
        returnedDAO = new ReturnedDAOImpl();
    }

    @Override
    public boolean insertBillInfo(BillInfo billInfo) {
        if (billInfo == null) {
            return false;
        }
        boolean success = false;
        success = billDAO.insertBill(billInfo.getBill());
        if (success) {
            for (PurchasedItem purchasedItem : billInfo.getPurchasedItems()) {
                if (purchasedItem.getStockItem().getQuantity() > 0) {
                    success = stockDAO.updateQuantity(purchasedItem.getStockItem());
                    if (!success) {
                        logger.error("failed to update stock quantity for the item id = " + purchasedItem.getStockItem().getItemId());
                    }
                } else {
                    //selling the last item from this stock
                    //success = stockDAO.deleteStockById(conn, purchasedItem.getStockItem().getStockId());
                }
                success = purchasedItemDAO.insert(purchasedItem, billInfo.getBill().getBillId());
                if (!success) {
                    logger.error("failed to insert data to stock_bill for the item id = " + purchasedItem.getStockItem().getItemId());
                }
            }
        }
        return success;
    }

    @Override
    public boolean finalize(BillInfo billInfo) {
        //since the billing process is finished set the state of the bill as completed
        billInfo.getBill().setStatus(3);
        return insertBillInfo(billInfo);
    }

    @Override
    public boolean suspend(BillInfo billInfo) {
        //since the billing process is suspended set the state of the bill as suspended
        billInfo.getBill().setStatus(2);
        return insertBillInfo(billInfo);
    }

    @Override
    public BillInfo getBillInfoByIdForGivenState(long billId, int state) {
        BillInfo billInfo = null;
        Bill bill = billDAO.getBillById(billId, state);
        List<PurchasedItem> purchasedItems = null;
        if (bill != null) {
            billInfo = new BillInfo(bill);
            billInfo.setBill(bill);
            purchasedItems = purchasedItemDAO.getPurchasedItems(billId);
            if (purchasedItems.size() == 0) {
                logger.error("no items found for the given bill id = " + billId);
            }
            for (PurchasedItem pItem : purchasedItems) {
                Stock s = stockDAO.getStockById(pItem.getStockItem().getStockId());
                pItem.setStockItem(s);
            }
            billInfo.setPurchasedItems(purchasedItems);
        }
        return billInfo;
    }

    @Override
    public List<BillInfo> getSuspendedBillInfos(long userId) {
        List<BillInfo> billInfos = new ArrayList<BillInfo>();
        List<Bill> suspendedBills = billDAO.getBillByUserIdAndState(userId, 2);
        if (suspendedBills.size() == 0) {
            logger.error("no suspended bills found for userId  = " + userId);
        }
        for (Bill bill : suspendedBills) {
            BillInfo billInfo = getBillInfoByIdForGivenState(bill.getBillId(), 2);
            billInfos.add(billInfo);
        }
        return billInfos;
    }

    @Override
    public boolean refund(List<ReturnedItem> returnedItems, long billId) {
        boolean success = false;
        BillInfo billInfo = getBillInfoByIdForGivenState(billId, 3);
        List<PurchasedItem> purchasedItems = billInfo.getPurchasedItems();
        for (PurchasedItem pItem : purchasedItems) {
            for (ReturnedItem retItem : returnedItems) {
                if (pItem.getStockItem().getItemCode().equals(retItem.getItem().getItemCode())) {
                    billInfo.getBill().setTotalAmount(billInfo.getBill().getTotalAmount() - (retItem.getSubTotal()));
                    pItem.setQuantity(pItem.getQuantity() - retItem.getQuantity());
                    pItem.setSubTotal(pItem.getSubTotal() - retItem.getSubTotal());
                    if (pItem.getQuantity() == 0) {
                        purchasedItemDAO.delete(pItem, billId);
                    } else {
                        success = purchasedItemDAO.update(pItem, billId);
                    }
                    if (success) {
                        retItem.setDate(DateTimeUtils.getDate());
                        success = returnedDAO.insert(retItem, billId);
                        if (!success) {
                            logger.error("Unable to insert data to refund for item " + retItem.getItem().getItemCode());
                        }
                    }
                }
            }
        }
        if (success) {
            success = billDAO.updateTotal(billInfo.getBill());
        }
        return success;
    }
}
